package ch02.classPath.Entry;

import sun.text.resources.iw.FormatData_iw_IL;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;

/**
 * ZipJarEntry 是 Entry 的实现类，适用于 classPath 为 zip 或者 jar 的时候
 */
public class ZipJarEntry extends Entry{
    String absPath;
    String zipName;

    public ZipJarEntry(String path){
        File dir = new File(path);
        if(dir.exists()){
            absPath = dir.getParentFile().getAbsolutePath();
            zipName = dir.getName();
            //去掉 .zip 或 .jar
            zipName = zipName.substring(0,zipName.length()-4);
        }
    }

    public ZipJarEntry(String path, String zipName) {
        File dir = new File(path, zipName);
        if (dir.exists()) {
            absPath = dir.getAbsolutePath();
            //去掉结尾的.zip或者.jar 千万别碰上其它情况,要不直接异常了;
            this.zipName = zipName.substring(0, zipName.length() - 4);
        }
    }

    /**
     * 从 zip 或者 jar 中加载 class 文件
     * @param className
     * @return
     * @throws IOException
     */
    @Override
    public byte[] readClass(String className) throws IOException {
        File file = new File(absPath);
        ZipInputStream zin = null;
        BufferedInputStream inputStream = null;
        ByteArrayOutputStream outputStream = null;

        ZipFile zf = new ZipFile(file);
        ZipEntry ze = zf.getEntry(className);
        if(ze == null){
            return null;
        }

        inputStream = new BufferedInputStream(zf.getInputStream(ze));
        outputStream = new ByteArrayOutputStream(1024);
        int size = 0;
        byte[] temp = new byte[1024];
        while ((size = inputStream.read(temp)) != -1){
            outputStream.write(temp,0,size);
        }

        if(zin != null){
            zin.closeEntry();
        }

        if(inputStream != null){
            inputStream.close();
        }

        if(outputStream != null){
            outputStream.close();
        }

        return outputStream.toByteArray();
    }

    @Override
    public String string() {
        return absPath;
    }
}
